package com.yuncheng.spcyApi.flow;

import cn.hutool.core.collection.CollectionUtil;
import com.yuncheng.entity.YcSysUser;
import com.yuncheng.vo.GetKsKz;
import com.yuncheng.vo.CurrentUserVo;
import org.apache.commons.collections.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yuncheng.spcyApi.bo.ParamsBo;
import com.yuncheng.spcyApi.busService.BusService;
import com.yuncheng.spcyApi.constant.common.LogConstant;
import com.yuncheng.spcyApi.constant.common.SpcyConstant;
import com.yuncheng.spcyApi.entity.*;
import com.yuncheng.exception.BusinessException;
import com.yuncheng.spcyApi.mapper.SpcySqsxXpjlMapper;
import com.yuncheng.spcyApi.service.*;
import com.yuncheng.spcyApi.utils.DateConvert;
import com.yuncheng.spcyApi.utils.GetCurrentUserUtils;
import com.yuncheng.spcyApi.utils.StringPatternUtils;
import com.yuncheng.spcyApi.vo.common.Result;
import com.yuncheng.spcyApi.vo.flow.AgentVo;
import com.yuncheng.spcyApi.vo.ndkp.NdkpFlowMapVo;
import com.yuncheng.spcyApi.vo.ndkp.NdkpJcyTjVo;
import com.yuncheng.spcyApi.vo.ndkp.NdkpXpjlVo;
import com.yuncheng.spcyApi.vo.spcy.SpcyReturnVo;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import utils.DateConversionUtils;
import utils.LogUtils;
import utils.ObjectToMapUtils;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 年度考评流程
 * @author hua
 */
@Component(value = "jcyNdkpFlowService")
public class JcyNdkpFlowService {
    private static final Logger log = LoggerFactory.getLogger(JcyNdkpFlowService.class);

    @Resource
    @Lazy
    private IYcSysUserService ycSysUserService;

    @Resource
    @Lazy
    private ISysUserFgldService sysUserFgldService;

    @Resource
    @Lazy
    private ISpcySqsxBaiscService spcySqsxBaiscService;

    @Resource
    @Lazy
    private SpcySqsxXpjlMapper spcySqsxXpjlMapper;

    @Resource
    @Lazy
    private ISpcySqsxXpjlService spcySqsxXpjlService;

    @Resource
    @Lazy
    private ISysUserPxjlService sysUserPxjlService;

    @Resource
    @Lazy
    private ISpcyKpNdpxjlService spcyKpNdpxjlService;

    @Resource
    @Lazy
    private ISpcyKpNdkpjhService spcyKpNdkpjhService;

    @Resource
    @Lazy
    private BusService busService;

    @Resource
    @Lazy
    private ISpcySqsxJobService spcySqsxJobService;

    @Resource
    @Lazy
    private ISysFlowNodeService sysFlowNodeService;

    @Resource
    private ISpcyKpNdkpBasicService spcyKpNdkpBasicService;

    @Resource
    @Lazy
    private FlowNodeService flowNodeService;

    @Resource
    @Lazy
    private ISpcyLogService spcyLogService;

    /**
     * 处理流程
     * @param flowVo
     * @param jobId
     * @param submitType
     * @param opinion
     * @return
     */
    public Result handleFlow(NdkpFlowMapVo flowVo, String jobId, String pid, String submitType, String opinion){
        return this.handleFlow(flowVo, null, jobId, pid, submitType, opinion);
    }
    public Result handleFlow(NdkpFlowMapVo flowVo, SpcySqsxJob nowJob, String jobId, String pid, String submitType, String opinion){
        if (StringUtils.isBlank(jobId)){
            throw new BusinessException("流程任务id参数丢失！");
        }

        // 当前流程任务
        if (nowJob == null) {
            nowJob = spcySqsxJobService.getById(jobId);
        }

        if (nowJob == null){
            return Result.error("当前流程任务不存在，请重试");
        }

        pid = nowJob.getFpid();
        if (StringUtils.isBlank(pid)){
            throw new BusinessException("业务参数为空！");
        }

        // 提交按钮
        if (submitType.equals(SpcyFlowConstant.SUBMIT_TYPE_SUBMIT)) {
            if (nowJob == null) {
                return Result.error("当前流程任务不存在");
            }

            if (nowJob.getFhjmc().equals(SpcyFlowConstant.NDKP_HJMC_GRZJ)){
                SpcyKpNdkpBasic ndkp = spcyKpNdkpBasicService.getById(pid);
                if (ndkp == null){
                    throw new BusinessException("没有相匹配的考评数据！");
                }

                if (StringUtils.isNotBlank(ndkp.getFkpjhid())) {
                    // 验证年度计划-截止日期
                    SpcyKpNdkpjh ndjh = spcyKpNdkpjhService.getById(ndkp.getFkpjhid());
                    if (ndjh != null && ndjh.getFkpjzrq() != null){
                        String jzrq = DateConversionUtils.DateToStringYYYYMMDD(ndjh.getFkpjzrq());
                        int flag = jzrq.compareTo(DateConversionUtils.DateToStringYYYYMMDD(new Date()));
                        if (flag > 0){
                            throw new BusinessException("提交失败，无法进行提交【个人总结】提交截止日期为["+jzrq+"]");
                        }
                    }
                }
            }

        }

        // 流程环节处理
        Result httpResult = handleNodeName(flowVo, submitType, nowJob, pid, opinion);
        if (!httpResult.isSuccess()){
            return httpResult;
        }else {
            // 最后一个环节提交
            if(submitType.equals(SpcyFlowConstant.SUBMIT_TYPE_SUBMIT)){

                if (nowJob.getFhjmc().equals(SpcyFlowConstant.NDKP_HJMC_GRZJ)){
                    // 培训时长
                    String pxsc = spcyKpNdpxjlService.getTotalLearningHoursTheCurrentYearByNdkpId(pid);

                    LambdaUpdateWrapper<SpcyKpNdkpBasic> updateWrapper = new LambdaUpdateWrapper<>();
                    updateWrapper.eq(SpcyKpNdkpBasic::getId, pid);

                    SpcyKpNdkpBasic updateBean = new SpcyKpNdkpBasic();
                    updateBean.setFjysc(pxsc);
                    updateBean.setFsftjkh(SpcyConstant.NDKP_SFTJKP_YES);
                    updateBean.setFndkpsj(new Date());
                    spcyKpNdkpBasicService.update(updateBean, updateWrapper);
                }

                if (nowJob.getFhjmc().equals(SpcyFlowConstant.NDKP_HJMC_END)) {
                    LambdaUpdateWrapper<SpcyKpNdkpBasic> updateWrapper = new LambdaUpdateWrapper<>();
                    updateWrapper.eq(SpcyKpNdkpBasic::getId, pid);

                    SpcyKpNdkpBasic updateBean = new SpcyKpNdkpBasic();
                    updateBean.setFlczt(SpcyFlowConstant.LCZT_LCBJ);
                    updateBean.setFwcsj(new Date());
                    spcyKpNdkpBasicService.update(updateBean, updateWrapper);
                }

            }
        }
        return httpResult;
    }

    /**
     * 流程环节处理
     * @param pid 业务id
     * @param flowVo 需要修改的字段内容
     * @param job 流程任务job
     * @param opinion 办理意见
     * @param submitType 提交、保存类型
     * @return true(),false(提示信息)
     */
    public Result handleNodeName(NdkpFlowMapVo flowVo, String submitType, SpcySqsxJob job, String pid, String opinion){
        HashMap<String, Object> map = flowVo.getMap();
        String smgflag = flowVo.getSmgflag(); // 短信发送标志
        String smsContent = flowVo.getSmsContent(); // 发送短信内容

        Result res = null;

        // 保存按钮
        if (submitType.equals(SpcyFlowConstant.SUBMIT_TYPE_SAVE)){
            Result result = this.updateKpxx(pid, map);
            if (!result.isSuccess()){
                return result;
            }
        }

        // 提交按钮
        if (submitType.equals(SpcyFlowConstant.SUBMIT_TYPE_SUBMIT)){
            Result result = this.updateKpxx(pid, map);
            if (!result.isSuccess()){
                return result;
            }

            if (job == null){
                throw new BusinessException("当前流程任务不存在！");
            }

            if (StringUtils.isBlank(job.getFhjmc())){
                throw new BusinessException("当前流程任务环节名称丢失！");
            }

            // 流程任务id
            String jobid = job.getId();

            // 提交流程任务,待办人是否为空，指定待办人
            if (StringUtils.isBlank(flowVo.getDbrid())) {
                // 按审查模式-提交-流程任务
                res = this.passJob(pid, jobid, job, opinion, flowVo.getNextNode(),flowVo.getNextNodeId(), null);
            }else {
                // 按审查模式-提交-流程任务
                res = this.passJob(pid, jobid, job, opinion, flowVo.getNextNode(),flowVo.getNextNodeId(),flowVo.getDbrid());
            }

            if (!res.isSuccess()){
                return res;
            }else {
                /**
                 * 接收返回的流程任务，如果返回的流程任务id不相等，发送短信
                 * 发送下环节短信
                 */
                if (StringUtils.isNotBlank(smgflag) && (smgflag.equals("是") || smgflag.equals("true"))){
                    busService.sendSmsToNextJob(jobid,smsContent);
                }
            }
        }

        return Result.ok("提交成功");
    }

    /**
     * 初始化流程
     * @param pid 业务id
     * @param currentUser 当前登陆用户
     * @return
     */
    public Result initJob(String pid, CurrentUserVo currentUser){
        return this.initJob(pid, currentUser, false);
    }

    /**
     * 初始化流程
     * @param pid 业务id
     * @param currentUser 当前登陆用户
     * @param isSendSms 是否发送短信
     * @return
     */
    public Result initJob(String pid, CurrentUserVo currentUser, boolean isSendSms){
        String lcmbCode = SpcyFlowConstant.KP_NDKH_FLOW_CODE;

        //获取流程模板的第一个环节
        SysFlowTemple code = sysFlowNodeService.getCode(lcmbCode);

        List<SysFlowNode> node = sysFlowNodeService.getFirstNode(code.getId());

        List<SpcySqsxJob> jobList = spcySqsxJobService.list(new LambdaQueryWrapper<SpcySqsxJob>()
                .eq(SpcySqsxJob::getFpid, pid)
                .eq(SpcySqsxJob::getFnodeid, node.get(0).getId())
                .ne(SpcySqsxJob::getFblzt, SpcyConstant.BLZT_YB));
        if (CollectionUtils.isNotEmpty(jobList)){
            return Result.error("当前申请事项环节["+node.get(0).getFjdmc()+"】已经初始化了!");
        }

        Result result = flowNodeService.createJob(lcmbCode,pid,"",node.get(0),null,null,currentUser);
        if (!result.isSuccess()){
            return result;
        }else {
            if (isSendSms) {
                SpcySqsxJob job = (SpcySqsxJob) result.getResult();
                if (job != null) {
                    String nextNodeSmsContent = busService.getNextNodeSmsContent(job, null);
                    busService.sendSmsToNodeDbr(job.getFdbrid(), job.getFlcmc() + "-" + job.getFhjmc(), nextNodeSmsContent);
                }
            }
        }

        return result;
    }

    /**
     * 提交流程
     * @param pid 业务id
     * @param jobid 流程任务id
     * @param job 当前流程任务
     * @param opinion 办理意见
     * @param nextNodeName 下环节结点名称
     * @param nextNodeId 下环节结点id
     * @param nextNodeDbrIds 下环节待办人
     * @return
     */
    private Result passJob(String pid,String jobid,SpcySqsxJob job, String opinion,String nextNodeName,String nextNodeId,String nextNodeDbrIds){
        if (job == null){
            job = spcySqsxJobService.getById(jobid);
        }
        String jobNodeName = job.getFhjmc(); // 当前环节名称

        Result httpResult = null;

        // 是否为最终结点
        if (StringUtils.isNotBlank(jobNodeName) && jobNodeName.equals(SpcyFlowConstant.NDKP_HJMC_END)){
            //办理掉当前环节
            httpResult = flowNodeService.doJob(job, opinion);
        }else {
            httpResult = flowNodeService.passJob(SpcyFlowConstant.KP_NDKH_FLOW_CODE, pid, jobid, opinion, nextNodeId, nextNodeDbrIds);
        }

        if (!httpResult.isSuccess()){
            return httpResult;
        }

        return Result.ok("success");
    }

    /**
     * 批量提交并设置考核结果
     * @param flowMapVo {ids: 年度考评ids；kpjg: 考核结果}
     */
    public void batchSubmitNdkp(NdkpFlowMapVo flowMapVo){
        if (StringUtils.isBlank(flowMapVo.getIds())){
            throw new BusinessException("参数为空！");
        }
        if (StringUtils.isBlank(flowMapVo.getKpjg())){
            throw new BusinessException("考核结果为空！");
        }

        List<String> idsList = StringPatternUtils.getListByIds(flowMapVo.getIds());
        CurrentUserVo currentUser = GetCurrentUserUtils.getCurrentUser();

        /** 流程更新 */
        LambdaUpdateWrapper<SpcySqsxJob> updateWrapperJob = new LambdaUpdateWrapper<>();
        updateWrapperJob.in(SpcySqsxJob::getFpid, idsList);
        updateWrapperJob.eq(SpcySqsxJob::getFhjmc, SpcyFlowConstant.NDKP_HJMC_END);
        updateWrapperJob.eq(SpcySqsxJob::getFhjmc, SpcyConstant.BLZT_DB);

        SpcySqsxJob updateJob = new SpcySqsxJob();
        updateJob.setFblr(currentUser.getName());
        updateJob.setFblsj(new Date());
        updateJob.setFblyj(flowMapVo.getKpjg());
        updateJob.setFblzt(SpcyConstant.BLZT_YB);
        updateJob.setFbllx(SpcyConstant.BLLX_BL);

        updateJob.setFblbm(currentUser.getDeptName());
        spcySqsxJobService.update(updateJob, updateWrapperJob);

        /** 年度考评 */
        LambdaUpdateWrapper<SpcyKpNdkpBasic> updateWrapperNdkp = new LambdaUpdateWrapper<>();
        updateWrapperNdkp.in(SpcyKpNdkpBasic::getId, idsList);

        SpcyKpNdkpBasic updateBean = new SpcyKpNdkpBasic();
        updateBean.setFndzhkpjg(flowMapVo.getKpjg());
        updateBean.setFlczt(SpcyFlowConstant.LCZT_LCBJ);
        updateBean.setFwcsj(new Date());
        spcyKpNdkpBasicService.update(updateBean, updateWrapperNdkp);
    }

    /**
     * 退回流程
     */
    public void getReturnUpperFlowJob(SpcyReturnVo spcyReturnVo){
        CurrentUserVo currentUser = GetCurrentUserUtils.getCurrentUser();
        if (currentUser == null){
            throw new BusinessException("登录已失效，请重新登录！");
        }

        if (StringUtils.isBlank(spcyReturnVo.getJobid())){
            throw new BusinessException("流程任务参数为空！");
        }

        if (StringUtils.isBlank(spcyReturnVo.getOpinion())){
            throw new BusinessException("请填写退回意见！");
        }

        SpcySqsxJob currentJob = spcySqsxJobService.getById(spcyReturnVo.getJobid());
        if (currentJob == null){
            throw new BusinessException("退回失败！当前流程任务不存在！");
        }

        SpcySqsxJob previousJob = getCurrentJobPrevious(spcyReturnVo.getJobid(), currentJob);
        if (previousJob == null){
            throw new BusinessException("退回失败！选中的退回环节不存在！");
        }

        // 退回功能
        Result result = flowNodeService.returnJob(spcyReturnVo.getJobid(), currentJob, spcyReturnVo.getShjid(), previousJob, spcyReturnVo.getOpinion(), currentUser);
        if (result.isSuccess()){

            if (StringUtils.isNotBlank(spcyReturnVo.getSmgflag()) && (spcyReturnVo.getSmgflag().equals("是") || spcyReturnVo.getSmgflag().equals("true"))) {
                SpcySqsxJob newPreviousJob = (SpcySqsxJob) result.getResult();
                // 发送退回短信
                String nextNodeSmsContent = busService.getNextNodeSmsContent(newPreviousJob, null);
                busService.sendNextNodeSmsContent(newPreviousJob, nextNodeSmsContent);
            }
        }
    }

    /**
     * 查询审评查验流程当前环节-上一环节
     * @param jobid 流程任务id
     * @return
     */
    private SpcySqsxJob getCurrentJobPrevious(String jobid, SpcySqsxJob nowJob){
        if (StringUtils.isBlank(jobid)){
            throw new BusinessException("流程任务参数为空！");
        }
        SpcySqsxJob previousJob = null;

        if (nowJob == null) {
            nowJob = spcySqsxJobService.getById(jobid);
            if (nowJob == null) {
                throw new BusinessException("当前流程任务不存在！");
            }
        }

        if (StringUtils.isBlank(nowJob.getFnodeid())){
            throw new BusinessException("当前流程任务结点配置不存在！");
        }

        List<SysFlowNode> previousNodeList = sysFlowNodeService.getPreviousNode(nowJob.getFnodeid());
        if (CollectionUtil.isEmpty(previousNodeList)){
            return previousJob;
        }

        LambdaQueryWrapper<SpcySqsxJob> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SpcySqsxJob::getFpid, nowJob.getFpid());
        queryWrapper.orderByAsc(SpcySqsxJob::getFfssj);

        if (previousNodeList.size() == 1) {
            queryWrapper.eq(SpcySqsxJob::getFnodeid, previousNodeList.get(0).getId());
        }else {
            List<String> preIdsList = previousNodeList.stream().map(SysFlowNode::getId).collect(Collectors.toList());
            queryWrapper.in(SpcySqsxJob::getFnodeid, preIdsList);
        }

        // 上环节结点id-办理过的流程任务
        List<SpcySqsxJob> previousJobList = spcySqsxJobService.list(queryWrapper);

        for (int i=0; i<previousJobList.size(); i++){
            previousJob = previousJobList.get(0);
        }

        return previousJob;
    }

    /**
     * 更新年度考评基本信息
     * @param ndkpid
     * @param buffer
     * @return
     */
    private Result updateKpxx(String ndkpid,HashMap<String,Object> buffer){
        if (StringUtils.isBlank(ndkpid)){
            return Result.error("年度考评id不能存在");
        }
        SpcyKpNdkpBasic updateNdkp = spcyKpNdkpBasicService.getById(ndkpid);
        if (updateNdkp == null){
            return Result.error("当前年度考评信息不存在，请重试");
        }
        Map<String, Object> oldMap = ObjectToMapUtils.objectToMap(updateNdkp);

        // 修改
        ConvertUtils.register(new DateConvert(), java.util.Date.class);
        try {
            BeanUtils.populate(updateNdkp, buffer);
        }catch (IllegalAccessException e) {
            log.error("出错-保存年度考评【非法访问异常 ，llegalAccessException】,{}",e.getMessage());
        } catch (InvocationTargetException e) {
            log.error("出错-保存年度考评【调用TargetException，InvocationTargetException】,{}",e.getMessage());
        }
        spcyKpNdkpBasicService.updateById(updateNdkp);

        String logContent = "基本信息修改: ";
        logContent += LogUtils.BeanModifyMsg(updateNdkp,oldMap);
        spcyLogService.addLogs(LogConstant.LOGS_SQSX_BASIC, logContent, ndkpid, LogConstant.LOGS_RS_YWZDXX, SpcyConstant.LOGS_SYS_TYPE_XG);

        return Result.ok();
    }

    /**
     * 计算参与考评人员的记录
     */
    public void jsJoinKpxx(String ndkpid){
        SpcyKpNdkpBasic ndkp = spcyKpNdkpBasicService.getById(ndkpid);

        String fuserid = "";
        String year = "";
        if (ndkp == null){
            return;
        }

        if (StringUtils.isNotBlank(ndkp.getFuserid())){
            fuserid = ndkp.getFuserid();
        }
        if (StringUtils.isNotBlank(ndkp.getFyear())){
            year = ndkp.getFyear();
        }

        // 年度检查情况
        NdkpJcyTjVo jcyTjVo = this.getHcyYearTj(fuserid, year);
        ndkp.setFzxxpcs(jcyTjVo.getZxxpcs());
        ndkp.setFsjjccs(jcyTjVo.getSjjccs());
        ndkp.setFjcqyzs(jcyTjVo.getJcqxzs());
        ndkp.setFdrzzcs(jcyTjVo.getDrzzcs());
        ndkp.setFdrzycs(jcyTjVo.getDrzycs());
        ndkp.setFcjjccs(jcyTjVo.getCjjccs());
        ndkp.setFcjpscs(jcyTjVo.getCjspcs());
        ndkp.setFcql(jcyTjVo.getAttendance() + "%");

        // 日常考核优秀
        ndkp.setFrckhyxcs(jcyTjVo.getRckhyxcs());
        ndkp.setFrckhyxl(jcyTjVo.getRckhyxl() + "%");

        // 日常考核合格
        ndkp.setFrckhhgcs(jcyTjVo.getRckhhgcs());
        ndkp.setFrckhhgl(jcyTjVo.getRckhhgl() + "%");

        // 日常考核不合格
        ndkp.setFrckhbhgcs(jcyTjVo.getRckhbhgcs());
        ndkp.setFrckhbhgl(jcyTjVo.getRckhbhgl() + "%");

        // 当前年度教育时长
        /*String jysc = sysUserPxjlService.getTotalLearningHoursTheCurrentYear(fuserid, year);
        ndkp.setFjysc(jysc);*/

        spcyKpNdkpBasicService.updateById(ndkp);
    }

    /**
     * 保存考评人员年度培训记录
     */
    public void saveNpryNdPxjl(ParamsBo paramsBo) throws InvocationTargetException, IllegalAccessException {
        if (StringUtils.isBlank(paramsBo.getId())){
            throw new BusinessException("参数为空！");
        }
        if (StringUtils.isBlank(paramsBo.getIds())){
            throw new BusinessException("请选择数据！");
        }

        SpcyKpNdkpBasic bean = spcyKpNdkpBasicService.getById(paramsBo.getId());
        if (bean == null){
            throw new BusinessException("没有相匹配的数据！");
        }

        List<String> idsList = StringPatternUtils.getListByIds(paramsBo.getIds());
        List<SysUserPxjl> pxjlList = sysUserPxjlService.listByIds(idsList);
        spcyKpNdpxjlService.genNdPxjl(pxjlList, paramsBo.getId());
    }

    /**
     * 获取 核查员年度的统计
     */
    private NdkpJcyTjVo getHcyYearTj(String fuserid, String year){

        int xpcs = 0; // 选派次数

        int btyxpcs = 0; // 不同意选派次数

        int tyxpcs = 0; // 同意选派次数

        int zxxpcs = 0; // 中心选派次数

        int sjjccs = 0; // 实际检查次数

        int jcqxzs = 0; // 检查企业总数

        int drzzcs = 0;  // 担任组长次数

        int drzycs = 0; // 担任组员次数

        int cjjccs = 0; // 参加检查次数

        int cjspcs = 0; // 参加评审次数

        String attendance = "0"; // 出勤率

        int rckhyxcs = 0; // 优秀次数
        String rckhyxl = "0"; // 优秀率

        int rckhhgcs = 0; // 合格次数
        String rckhhgl = "0"; // 合格率

        int rckhbhgcs = 0; // 不合格次数
        String rckhbhgl = "0"; // 不合格率

        NdkpXpjlVo ndkpXpjlVo = new NdkpXpjlVo();
        ndkpXpjlVo.setFuserid(fuserid);
        ndkpXpjlVo.setYear(year);
        List<NdkpXpjlVo> xpjlVoList = spcySqsxXpjlMapper.getNdkpXpjl(ndkpXpjlVo);
        if (CollectionUtils.isEmpty(xpjlVoList)){

        }else {
            // 中心选派次数
            zxxpcs = xpjlVoList.stream()
                    .filter(c -> c.getFhbjczt() == 0)
                    .collect(Collectors.toList()).size();

            // 实际检查次数
            List<NdkpXpjlVo> sjjccsList = xpjlVoList.stream()
                    .filter(c -> StringUtils.isNotBlank(c.getFsftyxp())
                            && c.getFsftyxp().equals(SpcyConstant.XPJL_SFTYXP_YES)
                            && c.getFhbjczt() == 0
                    )
                    .collect(Collectors.toList());
            sjjccs = sjjccsList.size();

            if (CollectionUtils.isNotEmpty(sjjccsList)){
                // 检查企业总数
                List<String> sqsxIdList = sjjccsList
                        .stream()
                        .map(NdkpXpjlVo::getFsqsxid)
                        .distinct()
                        .collect(Collectors.toList());
                jcqxzs = sqsxIdList.size();

                /*List<SpcySqsxBasic> sqsxList = new ArrayList<>();
                List<SpcySqsxBasic> distSqsxList = new ArrayList<>();*/
                /*if (CollectionUtils.isNotEmpty(sqsxIdList)) {
                    sqsxList = spcySqsxBaiscService.listByIds(sqsxIdList);
                }*/
                /*if (CollectionUtils.isNotEmpty(sqsxList)) {
                    distSqsxList = sqsxList.stream().distinct().collect(Collectors.toList());
                }*/


                // 担任组长次数
                List<NdkpXpjlVo> zzList = sjjccsList.stream()
                        .filter(c -> StringUtils.isNotBlank(c.getFssk())
                                && c.getFssk().contains(SpcyConstant.HCY_SSK_ZZ)
                        )
                        .collect(Collectors.toList());
                drzzcs = zzList.size();

                // 担任组员次数
                List<NdkpXpjlVo> zyList = sjjccsList.stream()
                        .filter(c -> StringUtils.isNotBlank(c.getFssk())
                                && c.getFssk().contains(SpcyConstant.HCY_SSK_ZY)
                        )
                        .collect(Collectors.toList());
                drzycs = zyList.size();

                // 优秀率
                List<NdkpXpjlVo> yxlList = sjjccsList.stream().filter(c -> StringUtils.isNotBlank(c.getFzhpj()) &&
                        c.getFzhpj().contains(SpcyConstant.XPJl_PJ_YX)).collect(Collectors.toList());
                rckhyxcs = yxlList.size();
                rckhyxl = spcySqsxXpjlService.jsNdkpCql(sjjccs, rckhyxcs);

                // 合格率
                List<NdkpXpjlVo> hglList = sjjccsList.stream().filter(c -> StringUtils.isNotBlank(c.getFzhpj()) &&
                        c.getFzhpj().contains(SpcyConstant.XPJl_PJ_HG)).collect(Collectors.toList());
                rckhhgcs = hglList.size();
                rckhhgl = spcySqsxXpjlService.jsNdkpCql(sjjccs, rckhhgcs);

                // 不合格率
                List<NdkpXpjlVo> bhgList = sjjccsList.stream().filter(c -> StringUtils.isNotBlank(c.getFzhpj()) &&
                        c.getFzhpj().contains(SpcyConstant.XPJl_PJ_BHG)).collect(Collectors.toList());
                rckhbhgcs = bhgList.size();
                rckhbhgl = spcySqsxXpjlService.jsNdkpCql(sjjccs, rckhbhgcs);
            }

            // 查验
            List<NdkpXpjlVo> cyXpList = xpjlVoList.stream()
                    .filter(c ->
                            StringUtils.isNotBlank(c.getFspcylx())
                            && c.getFspcylx().equals(SpcyConstant.FLOW_TYPE_CY)
                            && c.getFhbjczt() == 0
                    )
                    .collect(Collectors.toList());

            // 审评
            /*List<NdkpXpjlVo> spXpList = xpjlVoList.stream().filter(c -> StringUtils.isNotBlank(c.getFspcylx()) &&
                    c.getFspcylx().equals(SpcyConstant.FLOW_TYPE_SP)).collect(Collectors.toList());*/

            // 参加检查次数
            List<NdkpXpjlVo> cjjcList = cyXpList.stream()
                    .filter(c -> StringUtils.isNotBlank(c.getFsftyxp())
                            && c.getFsftyxp().equals(SpcyConstant.XPJL_SFTYXP_YES)
                    )
                    .collect(Collectors.toList());
            cjjccs = cjjcList.size();
            tyxpcs = cjjcList.size(); // 查验-同意选派次数

            // 不同意选派次数
            List<NdkpXpjlVo> btyxpcsList = cyXpList.stream()
                    .filter(c -> StringUtils.isNotBlank(c.getFsftyxp())
                            && c.getFsftyxp().equals(SpcyConstant.XPJL_SFTYXP_NO))
                    .collect(Collectors.toList());
            btyxpcs = btyxpcsList.size(); // 查验-不同意选派次数

            // 参加评审次数
            /*List<NdkpXpjlVo> cjspcsList = spXpList.stream().filter(c -> StringUtils.isNotBlank(c.getFsftyxp()) &&
                    c.getFsftyxp().equals(SpcyConstant.XPJL_SFTYXP_YES)).collect(Collectors.toList());
            cjspcs = cjspcsList.size();*/

            attendance = spcySqsxXpjlService.jsNdkpCql(zxxpcs, sjjccs); // 出勤率
        }

        xpcs = tyxpcs + btyxpcs; // 查验-总选派次数

        Map map = new HashMap();
        NdkpJcyTjVo tjVo = new NdkpJcyTjVo();

        tjVo.setXpcs(xpcs); // 总选派次数

        tjVo.setBtyxpcs(btyxpcs); // 不同意选派次数

        tjVo.setTyxpcs(tyxpcs); // 同意选派次数

        tjVo.setZxxpcs(zxxpcs); // 中心选派次数

        tjVo.setSjjccs(sjjccs); // 实际检查次数

        tjVo.setJcqxzs(jcqxzs); // 检查企业总数

        tjVo.setDrzzcs(drzzcs); // 担任组长次数

        map.put("drzycs", drzycs); // 担任组员次数
        tjVo.setDrzycs(drzycs);

        tjVo.setCjjccs(cjjccs); // 参加检查次数

        tjVo.setCjspcs(cjspcs); // 参加评审次数

        tjVo.setAttendance(attendance); // 出勤率 zxxpcs/sjjccs

        tjVo.setRckhyxcs(rckhyxcs); // 优秀次数

        tjVo.setRckhyxl(rckhyxl); // 优秀率

        tjVo.setRckhhgcs(rckhhgcs); // 合格次数

        tjVo.setRckhhgl(rckhhgl); // 合格率

        tjVo.setRckhbhgcs(rckhbhgcs); // 不合格次数


        tjVo.setRckhbhgl(rckhbhgl); // 不合格率

        return tjVo;
    }

    /**
     * 获取年度选派统计
     */
    public SpcyKpNdkpBasic getNdXpTj(String fywflcode,String year){
        CurrentUserVo currentUser = GetCurrentUserUtils.getCurrentUser();
        String fuserid = currentUser.getId();

        SpcyKpNdkpBasic ndkp = new SpcyKpNdkpBasic();

        NdkpXpjlVo ndkpXpjlVo = new NdkpXpjlVo();
        ndkpXpjlVo.setFuserid(fuserid);
        ndkpXpjlVo.setFywflcode(fywflcode);
        ndkpXpjlVo.setYear(year);
        List<NdkpXpjlVo> xpjlVoList = spcySqsxXpjlMapper.getNdkpXpjl(ndkpXpjlVo);
        if (CollectionUtils.isEmpty(xpjlVoList)){
            ndkp.setFzxxpcs(0);
            ndkp.setFsjjccs(0);
            ndkp.setFjcqyzs(0);
            ndkp.setFdrzzcs(0);
            ndkp.setFdrzycs(0);
            ndkp.setFcjjccs(0);
            ndkp.setFcjpscs(0);
            ndkp.setFcql("0");
            return ndkp;
        }

        // 中心选派次数
        int zxxpcs = 0;
        zxxpcs = xpjlVoList.size();

        // 实际检查次数
        int sjjccs = 0;
        List<NdkpXpjlVo> sjjccsList = xpjlVoList.stream().filter(c -> StringUtils.isNotBlank(c.getFsftyxp()) &&
                c.getFsftyxp().equals(SpcyConstant.XPJL_SFTYXP_YES)).collect(Collectors.toList());
        sjjccs = sjjccsList.size();

        // 检查企业总数
        int jcqxzs = 0;
        List<String> sqsxIdList = new ArrayList<>();
        List<SpcySqsxBasic> sqsxList = new ArrayList<>();
        List<SpcySqsxBasic> distSqsxList = new ArrayList<>();
        sqsxIdList = xpjlVoList.stream().map(NdkpXpjlVo::getFsqsxid).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(sqsxIdList)){
            sqsxList = spcySqsxBaiscService.listByIds(sqsxIdList);
        }
        if (CollectionUtils.isNotEmpty(sqsxList)){
            distSqsxList = sqsxList.stream().distinct().sorted().collect(Collectors.toList());
        }
        jcqxzs = distSqsxList.size();

        // 担任组长次数
        int drzzcs = 0;
        List<NdkpXpjlVo> zzList = xpjlVoList.stream().filter(c -> StringUtils.isNotBlank(c.getFssk()) &&
                c.getFssk().contains(SpcyConstant.HCY_SSK_ZZ)).collect(Collectors.toList());
        drzzcs = zzList.size();

        // 担任组员次数
        int drzycs = 0;
        List<NdkpXpjlVo> zyList = xpjlVoList.stream().filter(c -> StringUtils.isNotBlank(c.getFssk()) &&
                c.getFssk().contains(SpcyConstant.HCY_SSK_ZY)).collect(Collectors.toList());
        drzycs = zyList.size();

        // 查验
        List<NdkpXpjlVo> cyXpList = xpjlVoList.stream().filter(c -> StringUtils.isNotBlank(c.getFspcylx()) &&
                c.getFspcylx().equals(SpcyConstant.FLOW_TYPE_CY)).collect(Collectors.toList());

        // 审评
        List<NdkpXpjlVo> spXpList = xpjlVoList.stream().filter(c -> StringUtils.isNotBlank(c.getFspcylx()) &&
                c.getFspcylx().equals(SpcyConstant.FLOW_TYPE_SP)).collect(Collectors.toList());

        // 参加检查次数
        int cjjccs = 0;
        List<NdkpXpjlVo> cjjcList = cyXpList.stream().filter(c -> StringUtils.isNotBlank(c.getFsftyxp()) &&
                c.getFsftyxp().equals(SpcyConstant.XPJL_SFTYXP_YES)).collect(Collectors.toList());
        cjjccs = cjjcList.size();

        // 参加评审次数
        int cjspcs = 0;
        List<NdkpXpjlVo> cjspcsList = spXpList.stream().filter(c -> StringUtils.isNotBlank(c.getFsftyxp()) &&
                c.getFsftyxp().equals(SpcyConstant.XPJL_SFTYXP_YES)).collect(Collectors.toList());
        cjspcs = cjspcsList.size();

        String attendance = spcySqsxXpjlService.jsNdkpCql(zxxpcs, sjjccs); // 出勤率

        ndkp.setFzxxpcs(zxxpcs);
        ndkp.setFsjjccs(sjjccs);
        ndkp.setFjcqyzs(jcqxzs);
        ndkp.setFdrzzcs(drzzcs);
        ndkp.setFdrzycs(drzycs);
        ndkp.setFcjjccs(cjjccs);
        ndkp.setFcjpscs(cjspcs);
        ndkp.setFcql(attendance);

        return ndkp;
    }

    /**
     * 获取当前流程任务相关信息
     * @param jobid 流程任务id
     */
    public Map getJobConcernByJobId(String jobid){
        Map map = new HashMap();

        // 当前流转记录
        SpcySqsxJob job = spcySqsxJobService.getById(jobid);
        if (job == null){
            log.error("当前流程任务id为【{}】的流转记录不存在",jobid);
            return map;
        }
        String ndkpid = job.getFpid();
        if (org.apache.commons.lang3.StringUtils.isBlank(ndkpid)){
            log.error("当前流程任务id为【{}】的流转记录中的年度考评id为空",jobid);
            return map;
        }

        // 申请事项基本信息
        SpcyKpNdkpBasic ndkpBasic = spcyKpNdkpBasicService.getById(ndkpid);

        /*LambdaQueryWrapper<SpcySqsxJob> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SpcySqsxJob::getFpid, ndkpid);
        queryWrapper.like(SpcySqsxJob::getFlcmc, SpcyFlowConstant.NDKP_LCMC);
        queryWrapper.orderByAsc(SpcySqsxJob::getFfssj);
        queryWrapper.orderByAsc(SpcySqsxJob::getCreateTime);
        List<SpcySqsxJob> jobList = spcySqsxJobService.list(queryWrapper);*/

        // 培训情况
        List<SpcyKpNdpxjl> pxjlList = spcyKpNdpxjlService.getNdpxjlByNdkpId(ndkpid);

        map.put("ndkp", ndkpBasic); // 年度考评基本信息
        map.put("job", job); // 当前流转记录
        map.put("jobHistoryList", spcySqsxJobService.selectHistoryListByFpidAndFlcmc(ndkpid, null)); // 流程任务流传记录
        map.put("pxjlList", pxjlList); // 培训情况

        // 获取下环节待办人
        try {
            map.putAll(this.getNextNodeDbr(jobid,job));
        }catch (Exception e){
            log.error("年度考评-获取当前流程任务相关信息-错误：{}", e.getMessage());
        }


        return map;
    }

    /**
     * 获取下环节待办人
     * @param jobid
     * @param job
     * @return
     */
    private Map getNextNodeDbr(String jobid,SpcySqsxJob job){
        Map map = new HashMap();

        Map nextDbr = this.getNowJobInNextDbrAndHandlePageUrl(jobid, job);
        String nextNodeId = ""; // 下结点id
        String nextNode = "办结"; // 下结点名称
        if (nextDbr.get("nextNode") != null) {
            SysFlowNode nextFlowNode = (SysFlowNode) nextDbr.get("nextNode");
            nextNodeId = nextFlowNode.getId();
            nextNode = nextFlowNode.getFjdmc();
        }
        List<AgentVo> dbrListByMap = this.getDbrListByMap(nextDbr);

        map.put("nextNodeDbrList", dbrListByMap); // 下环节待办人list

        map.put("nextNode", nextNode); // 下流程结点名称
        map.put("nextNodeId", nextNodeId); // 下流程结点id

        return map;
    }

    /**
     * 获取下一个环节名称和待办人
     * @param job 流程任务
     * @param jobid 流程任务id
     * @return
     * {
     *     dbrId
     *     dbr:
     *     nextNode：下流程结点
     *     handlePageUrl：办理页面路径
     * }
     */
    private Map getNowJobInNextDbrAndHandlePageUrl(String jobid, SpcySqsxJob job){
        if (job == null && StringUtils.isNotBlank(jobid)){
            job = spcySqsxJobService.getById(jobid);
        }
        String flowCode = SpcyFlowConstant.KP_NDKH_FLOW_CODE;
        return flowNodeService.getNowJobInNextDbrAndHandlePageUrl(flowCode, job, null);
    }

    /**
     * 将待办人map转为List
     * @param map { dbrId: 待办人id ; dbr: 待办人 }
     */
    private List<AgentVo> getDbrListByMap(Map map){
        String dbrids = map.get("dbrId").toString(); // 待办人id
        String dbrs = map.get("dbr").toString(); // 待办人

        List<AgentVo> agentList = new ArrayList<>();

        if (StringUtils.isNotBlank(dbrids)) {
            String agentIds[] = dbrids.split(",|，");
            String agentNames[] = dbrs.split(",|，");

            for (int i = 0; i < agentIds.length; i++) {
                AgentVo agentVo = new AgentVo();
                agentVo.setDbrid(agentIds[i]);
                agentVo.setDbr(agentNames[i]);
                agentList.add(agentVo);
            }
        }

        return agentList;
    }

    /**
     * 获取当前环节待办人
     * @param pid 业务id
     * @param nodeName 环节名称
     * @return
     */
    public Map getNodeDbr(String pid, String nodeName){
        Map map = new HashMap();
        String dbrId = "";
        String dbr = "";

        String dept = "办公室";
        String fywflcode = "";
        SpcyKpNdkpBasic ndkp = spcyKpNdkpBasicService.getById(pid);
        if (ndkp != null && StringUtils.isNotBlank(ndkp.getFywflcode())){
            fywflcode = ndkp.getFywflcode();
        }

        if (StringUtils.isNotBlank(fywflcode)){
            dept = SpcyConstant.getYwclNameByCode(fywflcode);
        }

        if (nodeName.equals(SpcyFlowConstant.NDKP_HJMC_GRZJ)){
            dbrId = ndkp.getFuserid();
            dbr = ndkp.getFusermc();
        }

        if (nodeName.equals(SpcyFlowConstant.NDKP_HJMC_KPSH)){
            // 科室负责人
            Map kzMap = getKsfzrByDeptName(dept);
            dbrId = kzMap.get("dbrId").toString();
            dbr = kzMap.get("dbr").toString();
        }

        if (nodeName.equals(SpcyFlowConstant.NDKP_HJMC_KPFH)){
            // 科室负责人
            Map kzMap = getKsfzrByDeptName(dept);
            dbrId = kzMap.get("dbrId").toString();
            dbr = kzMap.get("dbr").toString();
        }

        // 待审批任务
        if (nodeName.equals(SpcyFlowConstant.NDKP_HJMC_KPSP)){
            // 分管领导
            Map kzMap = getKsFgldByDeptName(dept);
            dbrId = kzMap.get("dbrId").toString();
            dbr = kzMap.get("dbr").toString();
        }


        map.put("dbrId",dbrId);
        map.put("dbr",dbr);
        return map;
    }

    // 对应科室的 科室负责人
    private Map getKsfzrByDeptName(String deptName){
        Map map = new HashMap();
        String dbrId = "";
        String dbr = "";
        List<GetKsKz> ksKzObject = new ArrayList<>();
        ksKzObject = ycSysUserService.getKsKzObject(deptName, SpcyConstant.GW_NAME_KZ);
        if (CollectionUtils.isNotEmpty(ksKzObject)) {
            for (GetKsKz ksKz : ksKzObject) {
                dbrId += ksKz.getId()+",";
                dbr += ksKz.getRealname()+",";
            }
        }

        map.put("dbrId",dbrId);
        map.put("dbr",dbr);
        return map;
    }

    // 获取对应科室的 分管领导
    private Map getKsFgldByDeptName(String deptName){
        Map map = new HashMap();
        String dbrId = "";
        String dbr = "";

        YcSysUser fgldUserBydept = sysUserFgldService.getFgldUserBydept(deptName);
        if (fgldUserBydept != null) {
            dbrId = fgldUserBydept.getId();
            dbr = fgldUserBydept.getRealname();
        }

        map.put("dbrId",dbrId);
        map.put("dbr",dbr);
        return map;
    }

}
